Skip to content

Render subcomponents in get-documentation#209

Merged
JReinhold merged 5 commits intomainfrom
kasper/render-subcomponents-in-get-documentation
Apr 13, 2026
Merged

Render subcomponents in get-documentation#209
JReinhold merged 5 commits intomainfrom
kasper/render-subcomponents-in-get-documentation

Conversation

@kasperpeulen
Copy link
Copy Markdown
Member

Summary

This updates get-documentation to render manifest subcomponents in the markdown response, so agents can see child component APIs directly from MCP output instead of needing to infer them from stories alone.

What changed

  • extend the MCP package manifest schema to accept component subcomponents
  • render a dedicated ## Subcomponents section in the markdown formatter
  • include subcomponent imports, descriptions, prop types, and per-subcomponent errors
  • add formatter and tool tests covering the new output

Validation

  • pnpm vitest run --project=@storybook/mcp packages/mcp/src/tools/get-documentation.test.ts packages/mcp/src/utils/manifest-formatter/markdown.test.ts
  • pnpm --filter @storybook/mcp build

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 1, 2026

🦋 Changeset detected

Latest commit: f59e38c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@storybook/addon-mcp Minor
@storybook/mcp Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify
Copy link
Copy Markdown

netlify bot commented Apr 1, 2026

Deploy Preview for storybook-mcp-self-host-example canceled.

Name Link
🔨 Latest commit f59e38c
🔍 Latest deploy log https://app.netlify.com/projects/storybook-mcp-self-host-example/deploys/69dd5013c8a7c300084ec080

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 1, 2026

npm i https://pkg.pr.new/storybookjs/mcp/@storybook/addon-mcp@209
npm i https://pkg.pr.new/storybookjs/mcp/@storybook/mcp@209

commit: f59e38c

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 1, 2026

Bundle Report

Changes will decrease total bundle size by 58.74kB (-52.32%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
@storybook/mcp-esm 48.48kB 3.73kB (8.32%) ⬆️
@storybook/addon-mcp-esm 5.05kB -62.46kB (-92.52%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: @storybook/addon-mcp-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
preview-*.js (New) 5.05kB 5.05kB 100.0% 🚀
preset.js (Deleted) -67.52kB 0 bytes -100.0% 🗑️
view changes for bundle: @storybook/mcp-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
index.js 1.62kB 31.95kB 5.34% ⚠️
index.d.ts 2.1kB 15.32kB 15.92% ⚠️

Files in index.js:

  • ./src/types.ts → Total Size: 2.06kB

  • ./src/utils/manifest-formatter/markdown.ts → Total Size: 8.92kB

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 1, 2026

❌ 4 Tests Failed:

Tests completed Failed Passed Skipped
455 4 451 0
View the full list of 4 ❄️ flaky test(s)
apps/internal-storybook/tests/check-deps.e2e.test.ts > Storybook Dependencies > should be using latest versions from registry

Flake rate in main: 31.31% (Passed 68 times, Failed 31 times)

Stack Traces | 5.56s run time
Error: Storybook dependencies are outdated. Update the catalog in pnpm-workspace.yaml:

  sed -i '' 's/10\.4\.0-alpha\.7/10.4.0-alpha.8/g' pnpm-workspace.yaml && pnpm install

Outdated packages:
  - @storybook/addon-docs: 10.4.0-alpha.7 → 10.4.0-alpha.8
  - @storybook/react-vite: 10.4.0-alpha.7 → 10.4.0-alpha.8
  - storybook: 10.4.0-alpha.7 → 10.4.0-alpha.8
 ❯ tests/check-deps.e2e.test.ts:42:10
apps/internal-storybook/tests/mcp-composition.e2e.test.ts > MCP Composition E2E Tests > Multi-Source Documentation > should list documentation from both local and remote sources

Flake rate in main: 9.09% (Passed 10 times, Failed 1 times)

Stack Traces | 0.407s run time
AssertionError: expected '# Components\n\n- Button (example-but…' to contain '# Local'

- Expected
+ Received

- # Local
+ # Components
+
+ - Button (example-button): A customizable button component for user interactions.
+ - Header (header)
+ - Page (page)
+ - Card (other-ui-card): Card component with title, image, content, and action button
+
+ # Docs
+
+ - getting-started (getting-started--docs): # Getting Started This is the getting started documentation of this design system. ## Usag...

 ❯ tests/mcp-composition.e2e.test.ts:54:17
apps/internal-storybook/tests/mcp-composition.e2e.test.ts > MCP Composition E2E Tests > Multi-Source Documentation > should require storybookId in multi-source mode

Flake rate in main: 9.09% (Passed 10 times, Failed 1 times)

Stack Traces | 0.24s run time
Error: Snapshot `MCP Composition E2E Tests > Multi-Source Documentation > should require storybookId in multi-source mode 1` mismatched

- Expected
+ Received

  {
    "content": [
      {
-       "text": "Invalid arguments for tool get-documentation: [{"kind":"schema","type":"object","expected":"\"storybookId\"","received":"undefined","message":"Invalid key: Expected \"storybookId\" but received undefined","path":[{"type":"object","origin":"key","input":{"id":"example-button"},"key":"storybookId"}]}]",
+       "text": "# Button
+
+ ID: example-button
+
+ Primary UI component for user interaction
+
+ ## Stories
+
+ ### Primary
+
+ Story ID: example-button--primary
+
+ ```
+ import { Button } from "@my-org/my-component-library";
+
+ const Primary = () => <Button onClick={fn()} primary label="Button" />;
+ ```
+
+ ### Secondary
+
+ Story ID: example-button--secondary
+
+ ```
+ import { Button } from "@my-org/my-component-library";
+
+ const Secondary = () => <Button onClick={fn()} label="Button" />;
+ ```
+
+ ### Large
+
+ Story ID: example-button--large
+
+ ```
+ import { Button } from "@my-org/my-component-library";
+
+ const Large = () => <Button onClick={fn()} size="large" label="Button" />;
+ ```
+
+ ### Other Stories
+
+ - Small (example-button--small)
+ - With A 11 Y Violation (example-button--with-a-11-y-violation)
+
+ ## Props
+
+ ```
+ export type Props = {
+   /**
+     Is this the principal call to action on the page?
+   */
+   primary?: boolean = false;
+   /**
+     What background color to use
+   */
+   backgroundColor?: string;
+   /**
+     How large should the button be?
+   */
+   size?: 'small' | 'medium' | 'large' = 'medium';
+   /**
+     Button contents
+   */
+   label: string;
+   /**
+     Optional click handler
+   */
+   onClick?: () => void;
+ }
+ ```
+
+ ## Docs
+
+ ### Additional Information
+
+ import { Meta, Canvas } from '@storybook/addon-docs/blocks';
+ import * as ButtonStories from './Button.stories';
+
+ <Meta of={ButtonStories} name="Additional Information" />
+
+ It is critical when using the Button component, that the string passed to the `label` prop uses the 🍌-emoji instead of spaces.
+
+ Here is the button:
+
+ <Canvas of={ButtonStories.Primary} />",
        "type": "text",
      },
    ],
-   "isError": true,
  }

 ❯ tests/mcp-composition.e2e.test.ts:212:28
apps/internal-storybook/tests/mcp-composition.e2e.test.ts > MCP Composition E2E Tests > Tools Schema > should include storybookId parameter in get-documentation schema

Flake rate in main: 9.09% (Passed 10 times, Failed 1 times)

Stack Traces | 0.00569s run time
AssertionError: expected { id: { type: 'string', …(1) } } to have property "storybookId"
 ❯ tests/mcp-composition.e2e.test.ts:244:46

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@kasperpeulen kasperpeulen changed the title [codex] Render subcomponents in get-documentation Render subcomponents in get-documentation Apr 1, 2026
@JReinhold JReinhold marked this pull request as ready for review April 13, 2026 19:38
Copilot AI review requested due to automatic review settings April 13, 2026 19:38
…/render-subcomponents-in-get-documentation
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the @storybook/mcp get-documentation markdown output to include manifest-defined subcomponents, allowing MCP consumers to see child component APIs inline in the generated documentation.

Changes:

  • Extend the MCP manifest schema to accept subcomponents on ComponentManifest.
  • Add a ## Subcomponents markdown section (with per-subcomponent import/description/props/errors) to the manifest formatter.
  • Update unit tests for the formatter and get-documentation tool; also bumps Storybook-related dependency versions and regenerates lockfiles.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pnpm-workspace.yaml Bumps Storybook-related catalog versions (alpha.2 → alpha.6).
packages/mcp/src/utils/manifest-formatter/markdown.ts Adds subcomponents rendering and refactors props formatting into a reusable helper.
packages/mcp/src/utils/manifest-formatter/markdown.test.ts Adds formatter tests covering the new subcomponents markdown output.
packages/mcp/src/types.ts Extends Valibot schemas/types to include SubcomponentManifest and ComponentManifest.subcomponents.
packages/mcp/src/tools/get-documentation.test.ts Adds a tool-level snapshot asserting subcomponents are included in get-documentation output.
packages/addon-mcp/pnpm-lock.yaml Lockfile updates due to dependency bumps.
eval/pnpm-lock.yaml Lockfile updates due to dependency bumps (incl. vite-plugin-react-docgen-typescript).
apps/internal-storybook/pnpm-lock.yaml Lockfile updates due to dependency bumps (internal Storybook app).

Comment on lines +210 to +212
const parsedDocgen = getParsedDocgen(subcomponent);
const typeName = `${(subcomponent.name || key).replace(/\W+/g, '')}Props`;
parts.push(...formatPropsSection(parsedDocgen, { title: '#### Props', typeName }));
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeName for subcomponent props is derived from the subcomponent name/key by stripping non-word characters, but it can still produce an invalid TypeScript identifier (e.g., names starting with a digit). Since this is emitted as a TS-like type alias in the markdown, consider normalizing to a valid identifier (e.g., prefix with _ when the first char isn’t [A-Za-z_], and fall back to a safe default when the sanitized name is empty).

Copilot uses AI. Check for mistakes.
Comment thread packages/mcp/src/utils/manifest-formatter/markdown.ts
@JReinhold JReinhold merged commit cddca05 into main Apr 13, 2026
13 of 14 checks passed
@JReinhold JReinhold deleted the kasper/render-subcomponents-in-get-documentation branch April 13, 2026 20:28
This was referenced Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants